package com.xyf.sys.interceptor;

import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson2.JSONObject;
import com.xyf.sys.domain.User;
import com.xyf.sys.service.IUserService;
import com.xyf.sys.util.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@WebFilter("/*")
@Slf4j
public class RequestHeaderParamFilter implements Filter {

    // 定义最低版本要求
    private static final int[] MIN_VERSION = {2, 3, 15};
    private String databaseName;  // 存储提取的数据库名称

    @Autowired
    private IUserService userService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化时获取数据库配置
        ServletContext servletContext = filterConfig.getServletContext();
        WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

        if (ctx == null) {
            throw new ServletException("Spring Context not initialized");
        }

        Environment env = ctx.getEnvironment();
        String dbUrl = env.getProperty("spring.datasource.url");  // 注意配置项名称需要与实际一致

        if (StringUtils.isBlank(dbUrl)) {
            throw new ServletException("Database URL configuration missing");
        }

        this.databaseName = extractDatabaseName(dbUrl);
        log.info("Initialized database name: {}", databaseName);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 版本验证结束----------------------------------------------------------
        // 在所有响应中添加数据库头
        response.setHeader("database", databaseName);
        if (request.getRequestURL().toString().contains("/common/upload")
                || request.getRequestURL().toString().contains("/user/edit")
                || request.getRequestURL().toString().contains("/order/payNotify")
                || request.getRequestURL().toString().contains("/wechat")
                || request.getRequestURL().toString().contains("/swagger")
                || request.getRequestURL().toString().contains("/v3")
                || request.getRequestURL().toString().contains("/order/refundNotify")) {
            chain.doFilter(request, response);
            return;
        }

        // 版本验证逻辑----------------------------------------------------------
        String sysVersion = request.getHeader("SYS-Version");
        if (StringUtils.isBlank(sysVersion)) {
            sendErrorResponse(response, 400, "缺少必要版本头");
            return;
        }
        try {
            if (!isVersionValid(sysVersion, MIN_VERSION)) {
                sendErrorResponse(response, 500, "需要升级版本到2.3.15或更高");
                return;
            }
        } catch (NumberFormatException e) {
            sendErrorResponse(response, 400, "版本格式错误");
            return;
        }
        // 如果openid不为空，则将其设置到请求体中的userId参数
        if (RequestMethod.POST.toString().equals(request.getMethod()) && StringUtils.isNotBlank(request.getHeader("openid"))){
            // 在这里根据具体情况修改requestBody中的userId参数
            // 读取请求体的原始数据
            StringBuilder requestBodyBuilder = new StringBuilder();
            try (BufferedReader reader = request.getReader()) {
                String line;
                while ((line = reader.readLine()) != null) {
                    requestBodyBuilder.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            String requestBody = setUserIdAndDeptId2RequestBody(requestBodyBuilder.toString(), request.getHeader("openid"), request.getHeader("DEPTID"), request.getHeader("APPID"));
            log.info("url {} body {}", request.getRequestURL().toString(), requestBody);
            System.out.println("url = " + request.getRequestURL() + "\n body = " + requestBody);
            // 重新设置请求体
            ModifiedHttpServletRequest modifiedRequest = new ModifiedHttpServletRequest(request, requestBody);
            // 继续处理请求
            chain.doFilter(modifiedRequest, response);
            return;
        }
        chain.doFilter(request, response);
    }


    @Override
    public void destroy() {
        // 销毁过滤器
    }

    // 数据库名称提取方法
    private String extractDatabaseName(String jdbcUrl) {
        Pattern pattern = Pattern.compile("jdbc:mysql://.*?/(.*?)(\\?|$)");
        Matcher matcher = pattern.matcher(jdbcUrl);
        return matcher.find() ? matcher.group(1) : "unknown_database";
    }
    private String setUserIdAndDeptId2RequestBody(String requestBody, String userId, String deptId, String appid) {
        try {
            JSONObject body = JSONObject.parseObject(requestBody);
            if (body != null) {
                if (!body.containsKey("userId") || body.get("userId") == null || body.get("userId").equals("")){
                    if (Validator.isMobile(userId)){
                        User user = userService.getByMobile(userId, appid);
                        userId = user.getId();
                    }
                    body.put("userId", userId);
                }
                if (StringUtils.isNotBlank(deptId) && StringUtils.isNotBlank(deptId.trim()) && !body.containsKey("deptId")){
                    body.put("deptId", Long.valueOf(deptId));
                }
                if (StringUtils.isNotBlank(appid) && StringUtils.isNotBlank(appid.trim()) && !body.containsKey("appid")){
                    body.put("appid", appid);
                }
                return body.toJSONString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return requestBody;
    }

    // 版本验证方法
    private boolean isVersionValid(String version, int[] minVersion) throws NumberFormatException {
        String[] parts = version.split("\\.");
        if (parts.length < minVersion.length) return false;

        for (int i = 0; i < minVersion.length; i++) {
            int currentPart = Integer.parseInt(parts[i]);
            if (currentPart < minVersion[i]) return false;
            if (currentPart > minVersion[i]) return true;
        }
        return true;
    }

    // 错误响应方法
    private void sendErrorResponse(HttpServletResponse response, int code, String message) throws IOException {
        response.setStatus(code);
        response.setContentType("application/json;charset=UTF-8");
        JSONObject res = new JSONObject();
        res.put("code", code);
        res.put("message", message);
        response.getWriter().write(res.toJSONString());
    }
}
